package chain_to_chain

import (
	"chain_bridge_service/configs"
	"chain_bridge_service/internal/pkg/core"
	"chain_bridge_service/internal/repository/mongodb/chain_config"
	chian_to_chain "chain_bridge_service/internal/repository/mongodb/chain_to_chain"
	"chain_bridge_service/internal/repository/mongodb/chain_token"
	chainUserConfig "chain_bridge_service/internal/repository/mongodb/chain_user_config"
	"context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

type CreateChainData struct {
	Id             string
	UserId         string
	ChainConfigId0 string
	ChainConfigId1 string
	Token0         string
	Token1         string
	Rate           string
}

type ChainData struct {
	ChainName      string `bson:"chainName" json:"chainName"`
	ChainConfigId  string `bson:"chainConfigId" json:"chainConfigId"`
	ChainId        uint64 `bson:"chainId" json:"chainId"`
	CollectAddress string `bson:"collectAddress" json:"collectAddress"`
}

func (s *service) Create(ctx core.Context, chainData *CreateChainData) error {
	model := chian_to_chain.NewModel()
	model.ChainConfigId0 = chainData.ChainConfigId0
	model.ChainConfigId1 = chainData.ChainConfigId1
	model.UserId = chainData.UserId
	model.Token0 = chainData.Token0
	model.Token1 = chainData.Token1
	model.Rate, _ = primitive.ParseDecimal128(chainData.Rate)
	err := model.Create(s.db.GetDb())
	return err
}

func (s *service) List(ctx core.Context, pageIndex uint, pageSize uint, chainData *CreateChainData) (productList []chian_to_chain.ChainToChain, err error) {
	model := chian_to_chain.NewModel()
	model.UserId = chainData.UserId
	list, err := model.List(s.db.GetDb(), pageIndex, pageSize)
	return list, err
}

func (s *service) Find(ctx core.Context, chainData *CreateChainData) ([]chain_config.ChainConfig, error) {
	model := chian_to_chain.NewModel()
	model.ChainConfigId0 = chainData.ChainConfigId0
	model.ChainConfigId1 = chainData.ChainConfigId1
	list, err := model.Find(s.db.GetDb())
	return list, err
}
func (s *service) FindToken(ctx core.Context, chainData *CreateChainData) ([]chain_token.ChainToken, error) {
	model := chian_to_chain.NewModel()
	model.Token0 = chainData.Token0
	model.Token1 = chainData.Token1
	list, err := model.FindToken(s.db.GetDb())
	return list, err
}
func (s *service) Update(ctx core.Context, chainData *CreateChainData) error {
	model := chian_to_chain.NewModel()
	model.Id = chainData.Id
	model.ChainConfigId0 = chainData.ChainConfigId0
	model.ChainConfigId1 = chainData.ChainConfigId1
	model.UserId = chainData.UserId
	model.Token0 = chainData.Token0
	model.Token1 = chainData.Token1
	model.Rate, _ = primitive.ParseDecimal128(chainData.Rate)
	err := model.Update(s.db.GetDb())
	return err

}

func (s *service) Delete(ctx core.Context, chainData *CreateChainData) error {
	model := chian_to_chain.NewModel()
	model.Id = chainData.Id
	err := model.Delete(s.db.GetDb())
	return err
}

func (s *service) Count(ctx core.Context, chainData *CreateChainData) (int64, error) {
	model := chian_to_chain.NewModel()
	model.UserId = chainData.UserId
	count, err := model.Count(s.db.GetDb())
	return count, err
}

func (s *service) ApiList(ctx core.Context, userId string) ([]ChainData, error) {
	model := chian_to_chain.NewModel()
	model.UserId = userId
	list, err := model.ApiList(s.db.GetDb(), userId)

	// 提取chainConfigId0到数组
	chainConfigIds := make(map[string]bool)
	for _, result := range list {
		chainConfigIds[result["chainConfigId0"].(string)] = true
		chainConfigIds[result["chainConfigId1"].(string)] = true
	}

	cfg := configs.Get().Mongodb
	configClient := s.db.GetDb().Database(cfg.Config.Name).Collection("chain_config")

	var Data struct {
		ChainName string `bson:"chainName" json:"chainName"`
		ChainId   uint64 `bson:"chainId" json:"chainId"`
	}

	var chainDataList []ChainData
	for key, _ := range chainConfigIds {
		objId, _ := primitive.ObjectIDFromHex(key)
		_ = configClient.FindOne(context.TODO(), bson.D{{"_id", objId}}).Decode(&Data)

		var chainData ChainData
		chainData.ChainName = Data.ChainName
		chainData.ChainConfigId = key
		chainData.ChainId = Data.ChainId

		chainUserInfo, err := chainUserConfig.FindOne(s.db.GetDb(), userId, key)
		if err != nil {
			return nil, err
		}
		chainData.CollectAddress = chainUserInfo.CollectAddress

		chainDataList = append(chainDataList, chainData)

	}

	return chainDataList, err
}

func (s *service) GetRate(ctx core.Context, data *CreateChainData) (chian_to_chain.ChainToChain, error) {
	model := chian_to_chain.NewModel()
	model.UserId = data.UserId
	model.Token0 = data.Token0
	model.Token1 = data.Token1
	model.ChainConfigId0 = data.ChainConfigId0
	model.ChainConfigId1 = data.ChainConfigId1
	result, err := model.FindOne(s.db.GetDb())
	return result, err
}
